/*
 *  This class is part of WorkTimeCalculator Android App
 *  Author: Domenico Pio Novelli
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package com.dpndeveloper.wtc;

import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;

import android.app.Activity;
import android.app.Dialog;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;

import com.dpndeveloper.wtc.adapter.WtcIntervalListAdapter;
import com.dpndeveloper.wtc.dataprovider.WtcInterval;
import com.dpndeveloper.wtc.dataprovider.WtcIntervalDataBaseHelper;
import com.dpndeveloper.wtc.dialogs.AboutDialog;
import com.dpndeveloper.wtc.dialogs.EndAtDialog;
import com.dpndeveloper.wtc.dialogs.IntervalDialog;
import com.dpndeveloper.wtc.dialogs.StartAtDialog;
import com.dpndeveloper.wtc.listener.OnIntervalSetEvent;
import com.dpndeveloper.wtc.listener.OnIntervalSetListener;
import com.dpndeveloper.wtc.util.TimeUtil;

/**
 * <p>
 * Main Activity: first activity of application <br>
 * This activity shows the state of work (working/not working), the info about
 * work of the current day, week and month, the list of work interval of current
 * day
 * <p>
 * 
 * @author Domenico Pio Novelli
 * 
 */
public class WtcMainActivity extends Activity implements OnClickListener,
		OnIntervalSetListener {

	/* Constants for dialogs */
	private static final int			START_AT_DIALOG_ID	= 1;
	private static final int			STOP_AT_DIALOG_ID	= 2;
	private static final int			ABOUT_DIALOG_ID		= 3;

	/* The last stored interval of current day */
	private WtcInterval					m_lastInterval;

	/* Button to perform the start or stop at current time */
	private Button						m_buttonStartEndWork;

	/* Instance of DatabaseHelper to manage WtcIntervals */
	private WtcIntervalDataBaseHelper	m_wtcIntervalDatabaseHelper;

	/* The interval of current day */
	private List<WtcInterval>			m_dayIntervals;

	@Override
	public void onCreate(Bundle savedInstanceState) {

		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		m_buttonStartEndWork = (Button) findViewById(R.id.buttonStartEndWork);
		m_buttonStartEndWork.setOnClickListener(this);

		ListView list = (ListView) findViewById(R.id.listViewElement);
		registerForContextMenu(list);

	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.activity_work_time_calculator_main,
				menu);
		return true;
	}

	@Override
	public boolean onPrepareOptionsMenu(Menu menu) {
		// If not working, enable StartAt
		if (m_lastInterval == null || m_lastInterval.getEndTime() != null) {
			menu.getItem(0).setEnabled(true);
			menu.getItem(1).setEnabled(false);
		} else {
			// If working, enable EndAt
			menu.getItem(0).setEnabled(false);
			menu.getItem(1).setEnabled(true);
		}
		menu.getItem(4).setEnabled(false);
		return true;
	}

	@Override
	public void onClick(View v) {
		// Event onClick from Start/Stop Button
		if (v.equals(m_buttonStartEndWork)) {
			Calendar now = Calendar.getInstance(TimeZone.getDefault());
			now.set(Calendar.SECOND, 00);
			now.set(Calendar.MILLISECOND, 00);
			if (m_lastInterval == null || m_lastInterval.getEndTime() != null) {
				// If last interval is null (no interval in current day) or last
				// interval is completed, insert a new interval with start time
				// at current time
				m_lastInterval = new WtcInterval();
				m_lastInterval.setStartTime(now);
				m_lastInterval.setEndTime(null);
				Log.v("onClick", "insert");
				m_wtcIntervalDatabaseHelper.insert(m_lastInterval);
			} else if (m_lastInterval.getEndTime() == null) {
				// If last interval is not completed, update the interval with
				// end time at current time
				m_lastInterval.setEndTime(now);
				Log.v("onClick", "update");
				m_wtcIntervalDatabaseHelper.update(m_lastInterval);
			}

			// refresh the content on activity
			refreshWorkingStatus();
		}
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case R.id.menu_start_by_time:
			showDialog(START_AT_DIALOG_ID);
			return true;
		case R.id.menu_stop_by_time:
			showDialog(STOP_AT_DIALOG_ID);
			return true;
		case R.id.menu_history:
			startActivity(new Intent(this, WtcHistoryActivity.class));
			return true;
		case R.id.menu_refresh:
			refreshWorkingStatus();
			return true;
		case R.id.menu_about:
			showDialog(ABOUT_DIALOG_ID);
			return true;
		case R.id.menu_settings:
			// TODO: Next functionality
			return true;
		default:
			return super.onOptionsItemSelected(item);
		}
	}

	@Override
	public void onIntervalSet(OnIntervalSetEvent event) {
		// refresh content if there is a modify in the intervals
		refreshWorkingStatus();
	}

	@Override
	public void onCreateContextMenu(ContextMenu menu, View v,
			ContextMenuInfo menuInfo) {
		// Context menu for Listview of Intervals
		if (v.getId() == R.id.listViewElement) {
			menu.add(0, 0, 0, R.string.modify);
			menu.add(0, 1, 1, R.string.delete);
		}
	}

	@Override
	public boolean onContextItemSelected(MenuItem item) {
		AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item
				.getMenuInfo();
		int menuItemIndex = item.getItemId();
		switch (menuItemIndex) {
		case 0:
			// Modify interval: open dialog
			IntervalDialog intervalDialog = new IntervalDialog(this,
					m_dayIntervals.get(info.position), this,
					getWtcIntervalDataBaseHelper(), false);
			intervalDialog.show();
			break;
		case 1:
			// Delete Interval
			Log.i("onContextItemSelected", "Selected Delete for element "
					+ info.position);
			getWtcIntervalDataBaseHelper().delete(
					m_dayIntervals.get(info.position));
			refreshWorkingStatus();
			break;
		default:
			break;
		}
		return true;
	}

	@Override
	protected void onPostResume() {
		// refresh activity when it is resumed
		refreshWorkingStatus();
		super.onPostResume();
	}

	@Override
	protected Dialog onCreateDialog(int id) {
		switch (id) {
		case START_AT_DIALOG_ID:
			return new StartAtDialog(this, m_lastInterval, this,
					m_wtcIntervalDatabaseHelper);
		case STOP_AT_DIALOG_ID:
			return new EndAtDialog(this, m_lastInterval, this,
					m_wtcIntervalDatabaseHelper);
		case ABOUT_DIALOG_ID:
			return new AboutDialog(this);
		default:
			return super.onCreateDialog(id);
		}
	}

	@Override
	protected void onPrepareDialog(int id, Dialog dialog) {
		switch (id) {
		case START_AT_DIALOG_ID:
			((StartAtDialog) dialog).setLastInterval(m_lastInterval);
			break;
		case STOP_AT_DIALOG_ID:
			((IntervalDialog) dialog).setWtcInterval(m_lastInterval);
			break;
		}
	}

	@Override
	protected void onDestroy() {
		getWtcIntervalDataBaseHelper().close();
		super.onDestroy();
	}

	/**
	 * Returns the instance of WtcIntervalDataBaseHelper
	 * 
	 * @return instance of WtcIntervalDataBaseHelper
	 */
	private WtcIntervalDataBaseHelper getWtcIntervalDataBaseHelper() {
		if (m_wtcIntervalDatabaseHelper == null) {
			m_wtcIntervalDatabaseHelper = new WtcIntervalDataBaseHelper(this);
		}
		return m_wtcIntervalDatabaseHelper;
	}

	/**
	 * Update the contents of Main Activity
	 */
	private void refreshWorkingStatus() {

		Calendar now = Calendar.getInstance(TimeZone.getDefault());
		now.setTime(new Date());
		Log.v("refreshWorkingStatus", "Now : " + TimeUtil.print(now));

		// current day at time 0:00
		Calendar today = Calendar.getInstance(TimeZone.getDefault());
		today.set(Calendar.HOUR_OF_DAY, 00);
		today.set(Calendar.MINUTE, 00);
		today.set(Calendar.SECOND, 00);
		today.set(Calendar.MILLISECOND, 00);
		Log.v("refreshWorkingStatus", "Today start :" + TimeUtil.print(today));

		List<WtcInterval> todayIntervals = getWtcIntervalDataBaseHelper()
				.selectByInterval(today, now);

		if (todayIntervals.size() == 0) {
			m_lastInterval = null;
		} else {
			// set the last interval to the last result of query (the results
			// are ordered by start date
			m_lastInterval = todayIntervals.get(todayIntervals.size() - 1);
		}
		Log.v("onPostResume", "today selection size: " + todayIntervals.size());

		// Update the content of text for worked time in the current day
		TextView todayInfoView = (TextView) findViewById(R.id.textViewTodayInfo);
		todayInfoView
				.setText(TimeUtil.getWorkTimeAsString(todayIntervals, now));

		// last Monday (first day of week) at time 0:00
		Calendar weekCalendar = Calendar.getInstance(TimeZone.getDefault());
		weekCalendar.clear();
		weekCalendar.set(Calendar.WEEK_OF_YEAR,
				today.get(Calendar.WEEK_OF_YEAR));
		weekCalendar.set(Calendar.YEAR, today.get(Calendar.YEAR));
		Log.v("onPostResume", "week start :" + TimeUtil.print(weekCalendar));

		// Perform a select of WtcIntervals in the current week
		List<WtcInterval> weekIntervals = getWtcIntervalDataBaseHelper()
				.selectByInterval(weekCalendar, now);
		Log.v("onPostResume", "week selection size: " + weekIntervals.size());

		// Update the content of text for worked time in the current week
		TextView weekInfoView = (TextView) findViewById(R.id.textViewWeekInfo);
		weekInfoView.setText(TimeUtil.getWorkTimeAsString(weekIntervals, now));

		// First day of current month at time 0:00
		Calendar monthCalendar = Calendar.getInstance(TimeZone.getDefault());
		monthCalendar.set(Calendar.DAY_OF_MONTH, 1);
		monthCalendar.set(Calendar.HOUR_OF_DAY, 00);
		monthCalendar.set(Calendar.MINUTE, 00);
		monthCalendar.set(Calendar.SECOND, 00);
		monthCalendar.set(Calendar.MILLISECOND, 00);
		monthCalendar.set(Calendar.YEAR, today.get(Calendar.YEAR));
		Log.v("onPostResume", "month start :" + TimeUtil.print(monthCalendar));

		List<WtcInterval> monthIntervals = getWtcIntervalDataBaseHelper()
				.selectByInterval(monthCalendar, now);
		Log.v("onPostResume", "month selection size: " + monthIntervals.size());

		// Update the content of text for worked time in the current week
		TextView monthInfoView = (TextView) findViewById(R.id.textViewMonthInfo);
		monthInfoView
				.setText(TimeUtil.getWorkTimeAsString(monthIntervals, now));

		// Update the text on top (working / not working)
		TextView workingText = (TextView) findViewById(R.id.textViewWorking);
		if (m_lastInterval != null && m_lastInterval.getEndTime() == null) {
			m_buttonStartEndWork.setText(R.string.workStop);
			workingText.setBackgroundColor(Color.GREEN);
			workingText.setText(getString(R.string.workingFrom,
					TimeUtil.toHoursMinutes(m_lastInterval.getStartTime())));
		} else {
			m_buttonStartEndWork.setText(R.string.workStart);
			workingText.setBackgroundColor(Color.RED);
			workingText.setText(R.string.notWorking);
		}

		// update the content of list of WtcInterval of current day
		updateList(todayIntervals);

	}

	/**
	 * Update the content of list of WtcInterval
	 * 
	 * @param intervales
	 *            the list of interval to put in the list
	 */
	private void updateList(List<WtcInterval> intervales) {
		m_dayIntervals = intervales;
		ListView lv = (ListView) findViewById(R.id.listViewElement);
		lv.setAdapter(new WtcIntervalListAdapter(this, m_dayIntervals, true));
	}

}
